#include "infra/base/ai_thread.h"

#include <unistd.h>

#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
#include "c/thread.h"
#include "c/sleep.h"
#include "c/timer.h"
#include "ffrt.h"
#else
#include <pthread.h>
#include <thread>
#endif

#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
#define pthread_create ffrt_thread_create
#define pthread_join ffrt_thread_join
#define pthread_detach ffrt_thread_detach
#define pthread_t ffrt_thread_t
#endif

namespace hiai {
class AIThread {
public:
    AIThread() {}
    ~AIThread() {}

    int Create(void *(*callBack)(void*), void *arg);
    int Join();
    int Detach();

private:
    pthread_t tid_{0};
};

int AIThread::Create(void *(*callBack)(void*), void *arg)
{
#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    auto handle = ffrt::submit_h([&, this] {
#endif
        (void)pthread_create(&this->tid_, nullptr, callBack, arg);

#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    });
    ffrt::wait({handle});
#endif
    return 0;
}

int AIThread::Join()
{
    if (tid_ == 0) {
        return -1;
    }

    (void)pthread_join(tid_, nullptr);

    return 0;
}

int AIThread::Detach()
{
    if (tid_ == 0) {
        return -1;
    }

    (void)pthread_detach(tid_);

    return 0;
}

std::shared_ptr<AIThread> AIThread_Create(void *(*callBack)(void*), void *arg)
{
    std::shared_ptr<AIThread> aiThread = std::make_shared<AIThread>();
    if (aiThread != nullptr) {
        if (aiThread->Create(callBack, arg) != 0) {
            return nullptr;
        }
    }

    return aiThread;
}

int AIThread_Join(const std::shared_ptr<AIThread>& aiThread)
{
    if (aiThread == nullptr) {
        return -1;
    }
    return aiThread->Join();
}

int AIThread_Detach(const std::shared_ptr<AIThread>& aiThread)
{
    if (aiThread == nullptr) {
        return -1;
    }
    return aiThread->Detach();
}

void AIThread_Usleep(int period)
{
#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    ffrt_usleep(period);
#else
    usleep(period);
#endif
}

void AIThread_Sleep_For(int period)
{
#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    ffrt::this_task::sleep_for(std::chrono::seconds(period));
#else
    std::this_thread::sleep_for(std::chrono::seconds(period));
#endif
}

int AIThread_Timer_Start(uint64_t timeout, void* data, HiaiTimerCallback cb, bool repeat)
{
#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    int handle = -1;
    auto task = ffrt::submit_h([&] {
        handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, repeat);
    });
    ffrt::wait({task});

    return handle;
#else
    (void)timeout;
    (void)data;
    (void)cb;
    (void)repeat;
    return -1;
#endif
}

int AIThread_Timer_Stop(int handle)
{
#if (defined(AI_SUPPORT_FFRT) && defined(__OHOS__))
    return ffrt_timer_stop(ffrt_qos_default, handle);
#else
    (void)handle;
    return -1;
#endif
}
}